/*=============================================================================
*
*   Copyright (C) 2020 All rights reserved.
*
*   Filename:		pore.hpp
*
*   Author: Wang Zhecheng - wangzhecheng@yeah.net
*
*   Date: 2020-03-05 04:58
*
*   Last Editors: Wang Zhecheng - wangzhecheng@yeah.net
*
*   Last modified:	2020-07-20 16:22
*
*   Description:
*
=============================================================================*/
#ifndef PORE_H
#define PORE_H

#include "../../geometry/shape/nodal_dof.hpp"
#include "../../model/solve/assemble_elemental_mat.hpp"

namespace geoxfem {

namespace model {
struct pore {};
}  // namespace model

namespace geometry {

template <>
template <typename Vertex>
void set_nodal_dofs<model::pore>::apply(Vertex& v) { /*{{{*/
  size_t node = v.getIndex();
  v.append("pore", model::Dof{node});
}; /*}}}*/

template <>
template <typename Vertex>
std::vector<model::Dof*> get_nodal_dofs<model::pore> /*{{{*/
  ::apply(Vertex& v) {
  return {v.getDof("pore")};
} /*}}}*/

template <>
template <typename DimensionType, typename degree>
std::vector<model::Dof*> get_elemental_dof<model::pore>::/*{{{*/
  apply(const geometry::ShapeInterface<DimensionType, degree>& shp) {
  std::vector<model::Dof*> doflist;
  for(auto& v : verticesIn(shp))
    doflist.emplace_back(v->toVertex().getDof("pore"));
  return doflist;
} /*}}}*/

}  // namespace geometry

namespace model {

template <>
template <typename DimensionType, typename degree>
MatrixXR assemble_gauss_kay<pore, pore>::/*{{{*/
  apply(const geometry::ShapeInterface<DimensionType, degree>& shp,
        const GaussPoint<DimensionType>&                       gp) {
  MatrixXR deriv = Deriv(shp, gp);
  MatrixXR perm  = ConductivityMatrix(gp);
  return deriv.transpose() * perm * deriv;
} /*}}}*/

template <>
template <typename TimeStep>
void update_neumann_dof<pore>::apply(const TimeStep& tstep, Dof& dof) { /*{{{*/
  _real dtime = tstep.getDurationTime();
  _real etime = tstep.getEndTime();
  if(dof.ifNeumann())
    dof.setBoundaryValue(dtime * dof.getTimeFunction()->getValueAt(etime));
  return;
} /*}}}*/

}  // namespace model
}  // namespace geoxfem
#endif /* PORE_H */
